<template>
  <div id="wrapper">
    <el-container style="height: 98vh;">
      <el-header>
        <el-row>
          <el-button :type="model===1?'primary':''" icon="el-icon-edit" circle @click="model=1"></el-button>
          <el-button :type="model===2?'primary':''" icon="el-icon-aim" circle @click="model=2"></el-button>
          <el-button icon="el-icon-message" circle></el-button>
          <el-button icon="el-icon-star-off" circle></el-button>
          <el-button icon="el-icon-delete" circle @click="clearCanvas"></el-button>
        </el-row>
      </el-header>
      <el-container>
        <el-aside width="200px">
          <el-color-picker
              v-model="color"
              show-alpha
              :predefine="predefineColors">
          </el-color-picker>
          <input id="color" type="color" v-model="color">
        </el-aside>
        <el-main>
          <div class="el-color-predefine__color-selector is-alpha" :style="{width: canvasWidth, height: canvasHeight}">
            <canvas id="canvas" :width="canvasWidth" :height="canvasHeight" style="border:1px dashed gray;"></canvas>
          </div>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import { Rect } from '/src/tool/tool'
export default {
  name: 'work-page',
  data: function () {
    return {
      canvasWidth: 800,
      canvasHeight: 800,
      cnv: null,
      cxt: null,
      model: 1,
      color: '#000',
      processed: [],
      mouse: null,
      width: 10,
      length: 64,
      rectArr: {},
      fillArr: [],
      predefineColors: [
        '#ff4500',
        '#ff8c00',
        '#ffd700',
        '#90ee90',
        '#00ced1',
        '#1e90ff',
        '#c71585',
        'rgba(255, 69, 0, 0.68)',
        'rgb(255, 120, 0)',
        'hsv(51, 100, 98)',
        'hsva(120, 40, 94, 0.5)',
        'hsl(181, 100%, 37%)',
        'hsla(209, 100%, 56%, 0.73)',
        '#c7158577'
      ]
    }
  },
  mounted () {
    this.canvasWidth = this.width * this.length
    this.canvasHeight = this.width * this.length
    this.onload()
  },
  methods: {
    fill () {
      // 创建一个二维数组，用于记录像素点是否已经被处理过
      this.processed = []
      for (let i = 0; i < this.length; i++) {
        this.processed[i] = []
      }

      // 获取鼠标点击位置的坐标
      const mouseX = Math.floor(this.mouse.x / this.width)
      const mouseY = Math.floor(this.mouse.y / this.width)

      // 获取点击位置的颜色信息
      let rect = this.getRectByMouse()
      let targetcolor = rect.color

      // 创建空的队列，用于存储待处理的像素点
      const queue = []

      // 将初始点击位置添加到队列中
      queue.push({x: mouseX, y: mouseY})

      // 循环处理队列中的像素点
      while (queue.length > 0) {
        // 取出队列中的第一个像素点
        const {x, y} = queue.shift()

        // 判断当前像素点是否已经被处理过
        if (this.processed[x][y]) {
          continue
        }

        // 获取当前像素点的颜色信息
        const currentPixelData = this.getRectByMouse(x, y)
        if (!currentPixelData) {
          continue
        }
        const currentcolor = currentPixelData.color

        // 判断当前像素点的颜色是否和目标颜色相同
        if (currentcolor === targetcolor) {
          // 设置当前像素点的颜色为填充颜色
          currentPixelData.fill(this.color)
          this.fillArr.push(currentPixelData)

          // 标记当前像素点已被处理
          this.processed[x][y] = true

          // 将当前像素点的上、下、左、右四个邻接像素点添加到队列中
          if (x > 0) queue.push({x: x - 1, y}) // 左
          if (x < this.length - 1) queue.push({x: x + 1, y}) // 右
          if (y > 0) queue.push({x, y: y - 1}) // 上
          if (y < this.length - 1) queue.push({x, y: y + 1}) // 下
        }
      }
      this.clearRectIndex()
    },
    isSameColor (color1, color2) {
      for (let i = 0; i < 4; i++) {
        if (color1[i] !== color2[i]) {
          return false
        }
      }
      return true
    },
    clearCanvas () {
      this.cxt.clearRect(0, 0, this.cnv.width, this.cnv.height)
    },
    onload: function () {
      // 1、获取canvas对象
      this.cnv = document.getElementById('canvas')
      // 2、获取上下文环境对象context
      this.cxt = this.cnv.getContext('2d')
      this.mouse = this.getMouse(this.cnv)
      // 3、开始绘制图形
      this.rectArr = {}
      for (let x = 0; x < this.length; x++) {
        for (let y = 0; y < this.length; y++) {
          let rect = new Rect(x, y, this.width, this.width, this.mouse, this.cxt)
          this.rectArr[x + '_' + y] = rect
        }
      }
      this.cnv.addEventListener('mousedown', () => {
        if (this.model === 1) {
          this.mousemove()
          this.cnv.addEventListener('mousemove', this.mousemove)
        } else if (this.model === 2) {
          this.fill()
        }
      })
      this.cnv.addEventListener('mouseup', () => {
        this.cnv.removeEventListener('mousemove', this.mousemove)
        this.clearRectIndex()
      })
    },
    clearRectIndex () {
      while (this.fillArr.length > 0) {
        let rect = this.fillArr.shift()
        rect.resetIndex()
      }
    },
    getRectByMouse (x, y) {
      let pos
      if (x === undefined && y === undefined) {
        pos = (Math.floor(this.mouse.x / this.width)) + '_' + (Math.floor(this.mouse.y / this.width)).toString()
      } else {
        pos = x + '_' + y
      }
      return this.rectArr[pos]
    },
    mousemove () {
      let rect = this.getRectByMouse()
      if (rect) {
        rect.fill(this.color)
        this.fillArr.push(rect)
      }
    },
    getMouse (element) {
      // 定义一个mouse的对象
      let mouse = { x: 0, y: 0 }
      // 为传入的元素添加mousemove事件
      this.addEvent(element, 'mousemove', function (e) {
        var x, y
        // 在IE中，event对象是作为window对象的一个属性存在
        e = e || window.event
        // 获取鼠标当前位置，并作兼容处理
        // 兼容Firefox、chrome、IE9及以上
        if (e.pageX || e.pageY) {
          x = e.pageX
          y = e.pageY
          // eslint-disable-next-line brace-style
        }
        // 兼容IE8及以下，以及混杂模式下的Chrome和Safari
        else {
          x = e.clientX + document.body.scrollLeft || document.documentElement.scrollLeft
          y = e.clientY + document.body.scrollTop || document.documentElement.scrollTop
        }
        // 将当前的坐标值减去canvas元素的偏移位置，则x、y为鼠标在canvas中的相对坐标
        x -= element.offsetLeft
        y -= element.offsetTop

        mouse.x = x
        mouse.y = y
      })
      // 返回值为mouse对象
      return mouse
    },
    addEvent (element, event, callback) {
      element.addEventListener(event, callback)
    }
  }
}
</script>

<style>
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: antiquewhite;
}

canvas{
  /*background-color: #888888;*/
  background-position: 0 0, 10px 10px;
  background-size: 20px 20px;
  margin: 0 auto;
}
</style>
